#include <QSerialPortInfo>
#include <QSettings>
#include "ConnectWindowRTU.h"
#include "ui_ConnectWindowRTU.h"

#define CONFIG_FILENAME "config.ini"

ConnectWindowRTU::ConnectWindowRTU(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ConnectWindowRTU)
{
    ui->setupUi(this);

    ui->comboBoxPort->installEventFilter(this);

    ui->comboBoxBaudrate->addItem("1200");
    ui->comboBoxBaudrate->addItem("2400");
    ui->comboBoxBaudrate->addItem("4800");
    ui->comboBoxBaudrate->addItem("9600");
    ui->comboBoxBaudrate->addItem("14400");
    ui->comboBoxBaudrate->addItem("19200");
    ui->comboBoxBaudrate->addItem("38400");
    ui->comboBoxBaudrate->addItem("56000");
    ui->comboBoxBaudrate->addItem("57600");
    ui->comboBoxBaudrate->addItem("115200");

    ui->comboBoxDatabits->addItem("8");
    ui->comboBoxDatabits->addItem("9");

    ui->comboBoxStopbits->addItem("1");
    ui->comboBoxStopbits->addItem("2");

    ui->comboBoxParity->addItem(QString("无校验"));
    ui->comboBoxParity->addItem(QString("奇校验"));
    ui->comboBoxParity->addItem(QString("偶校验"));

    connect(ui->comboBoxPort, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged), this, &ConnectWindowRTU::portChanged);
    connect(ui->comboBoxParity, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ConnectWindowRTU::parityChanged);

    connect(ui->btnConnect, &QPushButton::clicked, this, &ConnectWindowRTU::connectClicked);

    QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
    for(int i = 0; i != infos.size(); i++)
    {
        ui->comboBoxPort->addItem(infos[i].portName());
    }

    QSettings settings(CONFIG_FILENAME, QSettings::IniFormat);

    ui->comboBoxPort->setCurrentIndex(ui->comboBoxPort->findText(settings.value("com").toString()));
    ui->comboBoxBaudrate->setCurrentText(settings.value("baudrate", 9600).toString());
    ui->comboBoxDatabits->setCurrentIndex(settings.value("databits", 0).toInt());
    ui->comboBoxStopbits->setCurrentIndex(settings.value("stopbits", 0).toInt());
    ui->comboBoxParity->setCurrentIndex(settings.value("parity", 0).toInt());
    ui->spinBoxSlaveAddress->setValue(settings.value("slaveaddr", 1).toInt());
}

ConnectWindowRTU::~ConnectWindowRTU()
{
    QSettings settings(CONFIG_FILENAME, QSettings::IniFormat);

    settings.setValue("com", ui->comboBoxPort->currentText());
    settings.setValue("baudrate", ui->comboBoxBaudrate->currentText());
    settings.setValue("databits", ui->comboBoxDatabits->currentIndex());
    settings.setValue("stopbits", ui->comboBoxStopbits->currentIndex());
    settings.setValue("parity", ui->comboBoxParity->currentIndex());
    settings.setValue("slaveaddr", ui->spinBoxSlaveAddress->value());

    delete ui;
}

void ConnectWindowRTU::connectClicked()
{
    this->close();  // 关闭窗口
    emit initConnect(ui->comboBoxPort->currentText(),
                     ui->comboBoxBaudrate->currentText().toInt(),
                     ui->comboBoxDatabits->currentText().toInt(),
                     ui->comboBoxStopbits->currentText().toInt(),
                     ui->comboBoxParity->currentIndex());
}

bool ConnectWindowRTU::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::MouseButtonPress)
    {
        if(watched == ui->comboBoxPort)
        {
            QString currText = ui->comboBoxPort->currentText();
            ui->comboBoxPort->clear();
            QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
            for(int i = 0; i != infos.size(); i++)
            {
                ui->comboBoxPort->addItem(infos[i].portName());
            }
            ui->comboBoxPort->setCurrentIndex(ui->comboBoxPort->findText(currText));
        }
    }
    return QMainWindow::eventFilter(watched, event);
}

void ConnectWindowRTU::portChanged(const QString &arg1)
{
    QSerialPortInfo info(arg1);
    ui->statusbar->showMessage(info.description());
}

void ConnectWindowRTU::parityChanged(int index)
{
    switch (index) {
    case 1:
    case 2:
        ui->comboBoxDatabits->setCurrentIndex(1);
        break;
    default:
        ui->comboBoxDatabits->setCurrentIndex(0);
        break;
    }
}

uint8_t ConnectWindowRTU::slaveAddress()
{
    return ui->spinBoxSlaveAddress->value();
}
